﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace 台签打印
{
    [TypeConverter(typeof(EnumConverter))]
    public enum MyFontStyle
    {
        常规 = 0, 加粗 = 1, 倾斜 = 2, 下划线 = 4
    }

    /// <summary>
    /// 字体大小处理 deepseek优化版
    /// </summary>
    public static class FontHandle
    {
        //获取字体列表， 排除英文字体
        public static string[] Fonts => new InstalledFontCollection().Families
                .Select(f => f.Name)
                .Where(f => Regex.IsMatch(f, "^[^A-Za-z]"))
                .ToArray();

        //参数
        public const int Max = 300;
        private const int MinFontSize = 5;
        private const float Precision = 0.5f;

        static readonly StringFormat _measureFormat = new StringFormat(StringFormat.GenericTypographic)
        {
            FormatFlags = StringFormatFlags.MeasureTrailingSpaces|StringFormatFlags.NoClip,
            Trimming = StringTrimming.None,
        };

        /// <summary>
        /// 获取适应目标区域的最佳字号
        /// </summary>
        public static Font GetMax(Graphics grfx, Size pixelSize, Font font1, string[] lines, float marginRatio)
        {
            //页面单位
            grfx.PageUnit = GraphicsUnit.Display;

            // 单次遍历获取最大宽高数据
            var maxWidthItem = new { Text = "", SizeF = new SizeF(0, 0) };
            var maxHeightItem = new { Text = "", SizeF = new SizeF(0, 0) };

            foreach (var line in lines)
            {
                var sizeF = grfx.MeasureString(line, font1, Point.Empty, _measureFormat);
                var item = new { Text = line, SizeF = sizeF.Pixel2Inch() };
                if (item.SizeF.Width > maxWidthItem.SizeF.Width) maxWidthItem = item;
                if (item.SizeF.Height > maxHeightItem.SizeF.Height) maxHeightItem = item;
            }

            // 使用初始字体避免重复创建
            var baseFont = new Font(font1.FontFamily, FontHandle.Max, font1.Style);

            // 分别计算两种字体尺寸
            var maxWidthFont = FontHandle.Get(grfx, pixelSize, baseFont, maxWidthItem.Text, marginRatio);
            var maxHeightFont = FontHandle.Get(grfx, pixelSize, baseFont, maxHeightItem.Text, marginRatio);

            // 选择较小的字体
            return maxWidthFont.Size <= maxHeightFont.Size ? maxWidthFont : maxHeightFont;
        }


        /// <summary>
        /// 获取适应目标区域的最佳字号
        /// </summary>
        public static Font Get(Graphics grfx, Size pixelSize, Font initialFont, string text, float MarginRatio)
        {
            //页面单位
            grfx.PageUnit = GraphicsUnit.Display;

            // 参数校验
            text = text?.NewLine() ?? string.Empty;

            // 计算有效绘制区域
            SizeF effectiveSize = new SizeF(pixelSize.Width * (1 - MarginRatio), pixelSize.Height * (1 - MarginRatio));

            // 使用二分查找优化算法
            return FindOptimalFont(grfx, text, initialFont, effectiveSize);
        }

        private static Font FindOptimalFont(Graphics grfx, string text, Font baseFont, SizeF maxSize)
        {
            float min = MinFontSize;
            float max = Math.Min(baseFont.Size, Max);
            Font bestFont = new Font(baseFont.FontFamily, MinFontSize, baseFont.Style);

            while (max - min > Precision)
            {
                float currentSize = (min + max) / 2;
                using (var testFont = new Font(baseFont.FontFamily, currentSize, baseFont.Style))
                {
                    // 使用精确测量方法
                    SizeF textSize = grfx.MeasureString(text, testFont, Point.Empty, _measureFormat);

                    if (textSize.Width <= maxSize.Width && textSize.Height <= maxSize.Height)
                    {
                        bestFont.Dispose();
                        bestFont = (Font)testFont.Clone();
                        min = currentSize;
                    }
                    else
                    {
                        max = currentSize;
                    }
                }
            }
            return bestFont;
        }

    }

}
